home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr49
/
imscale.zip
/
SCALE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-17
|
9KB
|
344 lines
/**********************************************************************
**
** SCALE.C
**
** Hi,
** I've gotten a lot of questions from people about the scaling routine
** in my Image Processing program called Improces. Quite a few folks
** have been interested in getting the source code to the program. As a
** matter of policy, I decided a long time ago not to give away any part
** of the source code to the Improces program. Sorry.
**
** Well, here is a _similar_ scaling routine. It works the same as the
** Improces one, only the one in the Improces program can handle images
** larger then 64K, and it does the scaling with a single buffer.
** Besides that, it's the same idea, and speed.
**
** If you'ld like the shareware version of Improces, it can be had from:
**
** Dust Devil BBS: (702)796-7134
**
** The Matrix BBS (This board is a monster!)
**
** 205-323-2016 for 2400 bps access only
** 205-323-6016 for HST/V.32bis access only (no 2400)
** 205-458-3449 for V.32bis access only (no 2400)
**
** or CompuServe
**
** I can be reached on any of the above BBS's, or CompuServe
** John Wagner, CIS-ID 72122,2412
**
**
** Legal stuff:
** Free, give it away, use it, not for resale, all that other
** good stuff... John Wagner, 1993
**
** Not responsible for any damage this code may cause!!!
**
** Small program that shows how to scale an when the source and
** destination are both under 64K. NO ERROR CHECKING IS PERFORMED!!!
**
***************************************************************************
***************************************************************************
** *
** WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!! *
** *
***************************************************************************
***************************************************************************
** Req. VGA hardware and file JOHN.CLB
** This program performs NO error checking, so make sure you have
** a VGA and the file JOHN.CLB. There is no error checking for
** memory allocation failures, add them if you like!
**
** It should be noted that this program will only work in mode 0x13
** without some major modifications on GetImage and PutImage. This
** program lives, eats and breaths on the fact that each pixel is
** 8 bits, and video memory is linear. (Just like Improces<g>).
**
** COMPILER: Borland C++ 3.1, Large model
**
** Command line: bcc -ml scale.c
**
** Should compile with Turbo C++ as well, tcc -ml scale.c
** and MS C family by modifying the #includes
**
**********************************************************************/
#include <dos.h>
#include <mem.h>
#include <malloc.h>
#include <io.h>
#include <fcntl.h>
#include <conio.h>
#include "scale.h"
/*********************************************************************
**
** main
**
*********************************************************************/
void main()
{
//These are the coords for a bounding box around John
static Rect JohnRect = {0, 0, 191, 164};
//this is the size of the screen in mode 0x13
static Rect ScreenRect = {0, 0, 319, 199};
//this is a rect that is smaller
static Rect SmallerRect = {200, 40, 310, 120};
Rect EffectRect;
int i;
//setup
SetVideoMode(0x13);
PalGrayScale();
LoadJohn();
//wait a sec...
GetKey();
//scale John to the screen rect
Scale(&JohnRect, &ScreenRect);
//wait another sec...
GetKey();
//reload
LoadJohn();
//wait...
GetKey();
//get small
Scale(&JohnRect, &SmallerRect);
//take a look-c...
GetKey();
//special effects!
do
{
memcpy(&EffectRect, &SmallerRect, sizeof(Rect));
for(i = 0 ; i < 30 ; i++)
{
EffectRect.Sx += 2;
EffectRect.Sy += 2;
EffectRect.Ex -= 2;
EffectRect.Ey -= 2;
Scale(&JohnRect, &EffectRect);
}
}while(!kbhit());
//flush
GetKey();
//and exit
SetVideoMode(3);
}
/*********************************************************************
**
** ImageSize
**
** Returns the number of bytes needed to capture a given image
**
*********************************************************************/
unsigned int ImageSize(pRect r)
{
return (unsigned)((unsigned)((r->Ex - r->Sx)+1) *
(unsigned)((r->Ey - r->Sy)+1));
}
/*********************************************************************
**
** GetImage
**
** Captures a given image and places it in a buffer
**
*********************************************************************/
void GetImage(pRect r, unsigned char *Buffer)
{
int y, Width;
unsigned char *Ptr = Buffer;
Width = r->Ex - r->Sx + 1;
for(y = r->Sy ; y <= r->Ey ; y++, Ptr+=Width)
memcpy(Ptr, VgaMem + (y * 320) + r->Sx, Width);
}
/*********************************************************************
**
** PutImage
**
** Takes an image from a buffer and places it on the screen
**
*********************************************************************/
void PutImage(pRect r, unsigned char * Buffer)
{
int y, Width;
unsigned char *Ptr = Buffer;
Width = r->Ex - r->Sx + 1;
for(y = r->Sy ; y <= r->Ey ; y++, Ptr+=Width)
memcpy(VgaMem + (y * 320) + r->Sx, Ptr, Width);
}
/*********************************************************************
**
** Scale
**
** Scales the image from Source to Dest
**
*********************************************************************/
void Scale(pRect Source, pRect Dest)
{
unsigned char *Image, *Screen, *PtrScreen;
float XRatio, YRatio, X, Y;
int Xc, Yc;
int DestWidth, DestHeight;
int SourceWidth, SourceHeight;
int *XPoints, *YPoints, Offset;
SourceWidth = Source->Ex - Source->Sx + 1;
SourceHeight = Source->Ey - Source->Sy + 1;
DestWidth = Dest->Ex - Dest->Sx + 1;
DestHeight = Dest->Ey - Dest->Sy + 1;
//ok, I lied, a little error checking
if(!SourceWidth || !SourceHeight || !DestWidth || !DestHeight)
return;
//should add error checking<g>
Image = (unsigned char *)malloc(ImageSize(Source));
Screen = (unsigned char *)malloc(ImageSize(Dest));
//capture the source image
GetImage(Source, Image);
/************************************************************************
Compute the scaling ratios
************************************************************************/
XRatio = (float) ( (float)SourceWidth /
(float)DestWidth );
YRatio = (float) ( (float)SourceHeight /
(float)DestHeight );
//alloc the look up table
XPoints = (int *)malloc(DestWidth * sizeof(int));
for( Xc=0, X = Source->Sx ; Xc < DestWidth ; X+=XRatio, Xc++ )
XPoints[Xc] = X;
//same for the y axis
YPoints = (int *)malloc(DestHeight * sizeof(int));
for( Yc=0, Y = Source->Sy ; Yc < DestHeight ; Y+=YRatio, Yc++ )
YPoints[Yc] = Y;
//use a pointer to run through the array
PtrScreen = Screen;
//This is it, actually scales the bitmap using the look up table
//to go from the dest to the source...
for( Yc = 0 ; Yc < DestHeight ; Yc++ )
{
Offset = YPoints[Yc] * SourceWidth;
for( Xc = 0 ; Xc < DestWidth ; Xc++)
*PtrScreen++ = Image[Offset + XPoints[Xc]];
}
//put the result on the screen
PutImage(Dest, Screen);
//free up the allocated memory
free(Screen);
free(Image);
free(YPoints);
free(XPoints);
}
/*********************************************************************
**
** LoadJohn
**
** Loads an image of yours truly directly into video memory
** (JOHN.CLB is a 320x200 clipboard image saved with Improces)
**
*********************************************************************/
void LoadJohn(void)
{
int FileHandle;
FileHandle = open("john.clb", O_RDONLY | O_BINARY);
read(FileHandle, VgaMem, 64000);
close(FileHandle);
}
/*********************************************************************
**
** SetVideoMode
**
** Mixes six oranges and two pineapples...
**
*********************************************************************/
void SetVideoMode(int Mode)
{
union REGS r;
r.x.ax = Mode;
int86(0x10, &r, &r); //click...
}
/*********************************************************************
**
** PalGrayScale
**
** Sets the VGA palette to grayscale
**
*********************************************************************/
void PalGrayScale(void)
{
register i=0;
//start at 0
outp(VgaStartColor, 0);
for(i = 0 ; i < 256 ; i++)
{
outp(VgaPort, i>>2); //Red
outp(VgaPort, i>>2); //Green
outp(VgaPort, i>>2); //Blue
}
}
/*********************************************************************
**
** GetKey
**
** Returns the key pressed
**
*********************************************************************/
int GetKey(void)
{
int Key;
Key = getch();
if(!Key)
Key = getch() + 256;
return Key;
}